
#ifndef SLED_CLASS_H 
#define SLED_CLASS_H 

#ifdef __cplusplus
extern "C"{
#endif

/*----------------------------------include-----------------------------------*/
#include "sclass_port.h"
#include "sclass.h"
#include "sled/sled_class/sled_public.h"
#include "sled/sled_class/sled_private.h"

/*----------------------------------typedef-----------------------------------*/
typedef struct sled_class
{
/** public: **/
    // sled_t class_public;
    SLED_PUBLIC_MEMBER
/** private: **/
    SLED_PRIVATE_MEMBER
}sled_class_t;
/*-----------------------------------macro------------------------------------*/
#define IO_DIR_OUT 0
#define IO_DIR_IN 1
/* Override */
void sled_init(sled_class_t *class);
void sled_set_mode(sled_class_t *class, slde_mode_t sled_mode);
slde_mode_t sled_get_mode(sled_class_t *class);
void sled_configure_pwm(sled_class_t *class, uint16_t duty);
void sled_configure_breathe(sled_class_t *class, uint16_t breathe_speed);
void sled_on_breathe(sled_class_t *class);
void sled_on1(sled_class_t *class);
void sled_on0(sled_class_t *class);
void sled_off(sled_class_t *class);

#define SLED_CONTRUCTOR(name,io_port) \
const sled_t *name; \
sled_class_t name##_sled_class_instance; \
static void name##_sled_init(void){sled_init(&name##_sled_class_instance);}  \
static slde_mode_t name##_GetCurMode(void){return sled_get_mode(&name##_sled_class_instance);} \
static void name##_SetMode(slde_mode_t mode){sled_set_mode(&name##_sled_class_instance,mode);} \
static void name##_ConfigurePWM(uint16_t duty){sled_configure_pwm(&name##_sled_class_instance,duty);} \
static void name##_ConfigurBreathe(uint16_t breathe_speed){sled_configure_breathe(&name##_sled_class_instance,breathe_speed);} \
static void name##_on_breathe(void){sled_on_breathe(&name##_sled_class_instance);} \
static void name##_on1(void){sled_on1(&name##_sled_class_instance);} \
static void name##_on0(void){sled_on0(&name##_sled_class_instance);} \
static void name##_off(void){sled_off(&name##_sled_class_instance);} \
static void name##_spin_lock(void){spin_lock(&(name##_sled_class_instance.lock));} \
static void name##_spin_unlock(void){spin_unlock(&(name##_sled_class_instance.lock));} \
static void name##_sled_constructor(void) \
{ \
    name##_sled_class_instance.port_io = io_port; \
    name##_sled_class_instance.init = name##_sled_init; \
    name##_sled_class_instance.GetCurMode = name##_GetCurMode; \
    name##_sled_class_instance.SetMode = name##_SetMode; \
    name##_sled_class_instance.ConfigurePWM = name##_ConfigurePWM; \
    name##_sled_class_instance.ConfigureBreathe = name##_ConfigurBreathe; \
    name##_sled_class_instance.ONBreathe = name##_on_breathe; \
    name##_sled_class_instance.ON1 = name##_on1; \
    name##_sled_class_instance.ON0 = name##_on0; \
    name##_sled_class_instance.OFF = name##_off; \
    name##_sled_class_instance.spin_lock = name##_spin_lock; \
    name##_sled_class_instance.spin_unlock = name##_spin_unlock; \
    name##_sled_class_instance.WorkMode = SLED_MODE_SWITCH; \
    name##_sled_class_instance.io_dir = IO_DIR_IN; \
    name##_sled_class_instance.pwm_handle = 0; \
    name##_sled_class_instance.breathe_timer_handle = 0; \
    name##_sled_class_instance.pwm_duty = 5000; \
    name##_sled_class_instance.breathe_speed = 1; \
    name##_sled_class_instance.breathe_index = 0; \
    name##_sled_class_instance.breathe_dir = 1; \
    name##_sled_class_instance.private_param = NULL; \
    name = (sled_t*)(&(name##_sled_class_instance)); \
} \
early_initcall(name##_sled_constructor); 


#ifdef __cplusplus
}
#endif

#endif